package com.diy.sigmund.diycommon.util.thread;

import org.junit.jupiter.api.Test;

/**
 * 线程中断测试
 *
 * @author ylm-sigmund
 * @since 2023/2/17 17:50
 */
public class ThreadInterrupt {

    @Test
    void test1() throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (; ; ) {
                    System.out.println(11);
                    if (Thread.currentThread().isInterrupted()) {
                        System.out.println("我运行结束啦");
                        break;
                    }
                }
            }
        });
        thread.start();
        Thread.sleep(3000);
        thread.interrupt();
        thread.join();
    }

    /**
     * <pre class="code">
     * 11
     * Thread.currentThread().isInterrupted()1:false
     * 11
     * Thread.currentThread().isInterrupted()1:false
     * 11
     * Thread.currentThread().isInterrupted()2:false
     * java.lang.InterruptedException: sleep interrupted
     * 	at java.lang.Thread.sleep(Native Method)
     * 	at com.diy.sigmund.diycommon.util.thread.ThreadInterrupt$2.run(ThreadInterrupt.java:39)
     * 	at java.lang.Thread.run(Thread.java:745)
     * Thread.currentThread().isInterrupted()3:false
     * Thread.currentThread().isInterrupted()4:true
     * 我运行结束啦
     *     </pre>
     */
    @Test
    void test2() throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (; ; ) {
                    System.out.println(11);
                    try {
                        Thread.sleep(1000);
                        System.out.println("Thread.currentThread().isInterrupted()1:" + Thread.currentThread().isInterrupted());
                    } catch (InterruptedException e) {
                        System.out.println("Thread.currentThread().isInterrupted()2:" + Thread.currentThread().isInterrupted());
                        e.printStackTrace();
                        System.out.println("Thread.currentThread().isInterrupted()3:" + Thread.currentThread().isInterrupted());
                        // 该异常会将中断标志位复位，需要手动再次中断
                        // 中断这个线程
                        Thread.currentThread().interrupt();
                        System.out.println("Thread.currentThread().isInterrupted()4:" + Thread.currentThread().isInterrupted());
                        // 测试此线程是否已中断。线程的中断状态不受此方法的影响。
                        if (Thread.currentThread().isInterrupted()) {
                            System.out.println("我运行结束啦");
                            break;
                        }
                    }
                }
            }
        });
        thread.start();
        Thread.sleep(3000);
        // 中断这个线程。
        thread.interrupt();
        thread.join();

        // 将线程中断状态改为false，在catch的InterruptedException块里面第一次调用返回false，第二次调用返回true

        // 测试当前线程是否已中断。该方法可以清除线程的中断状态。换句话说，如果这个方法连续被调用两次，
        // 那么第二次调用将返回false(除非当前线程在第一次调用清除中断状态之后，在第二次调用检查中断状态之前再次被中断)。
        // System.out.println(Thread.interrupted());
        // System.out.println(Thread.interrupted());
    }

    /**
     * 如果线程被阻塞，将不会检查该变量，但是调用interrupt()之后，线程就可以结束阻塞状态，能够检查该变量
     */
    private volatile boolean flag = false;

    @Test
    void test3() throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!flag) {
                    System.out.println(11);
                    try {
                        Thread.sleep(1000);
                        System.out.println("Thread.currentThread().isInterrupted()1:" + Thread.currentThread().isInterrupted());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("我运行结束啦");
            }
        });
        thread.start();
        Thread.sleep(3000);
        flag = true;
        thread.interrupt();
        thread.join();
    }

}
